package com.pt25.service.sys.domain.admin.service.impl;

import com.pt25.base.dep.redis.RedisService;
import com.pt25.base.exception.BizException;
import com.pt25.base.model.common.constants.RedisConstant;
import com.pt25.base.util.CollectionUtil;
import com.pt25.base.util.PageUtil;
import com.pt25.service.sys.domain.admin.ddo.AdminRole;
import com.pt25.service.sys.domain.admin.factory.AdminFactory;
import com.pt25.service.sys.domain.admin.service.AdminRoleService;
import com.pt25.service.sys.repository.mysql.persistence.AdminRolePermissionRepo;
import com.pt25.service.sys.repository.mysql.persistence.AdminRoleRepo;
import com.pt25.service.sys.repository.mysql.persistence.AdminUserRoleRepo;
import com.pt25.service.sys.repository.mysql.po.AdminRolePermissionPo;
import com.pt25.service.sys.repository.mysql.po.AdminRolePo;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Service
public class AdminRoleServiceImpl implements AdminRoleService {
    @Resource
    private RedisService redisService;

    @Resource
    private AdminRoleRepo adminRoleRepo;

    @Resource
    private AdminUserRoleRepo adminUserRoleRepo;

    @Resource
    private AdminRolePermissionRepo adminRolePermissionRepo;

    @Resource
    private AdminFactory adminFactory;

    @Transactional
    @Override
    public void addAdminRole(AdminRole adminRole) {
        if (null == adminRoleRepo.getAdminRoleByRole(adminRole.getRole())) {
            //保存角色
            AdminRolePo adminRolePO = adminFactory.adminRole2AdminRolePO(adminRole);
            adminRolePO.setId(redisService.genAutoIncrID(RedisConstant.CLUSTER1, AdminRolePo.key));
            adminRoleRepo.save(adminRolePO);
            //保存角色权限
            adminRole.setId(adminRolePO.getId());
            saveRolePermission(adminRole);
            return;
        }
        throw new BizException("角色:" + adminRole.getRole() + "已经存在！");
    }

    @Transactional
    @Override
    public void delAdminRole(Long roleId) {
        //删除角色
        adminRoleRepo.removeById(roleId);
        //删除角色权限
        adminRolePermissionRepo.delRolePermissionByRoleId(roleId);
        //删除用户角色
        adminUserRoleRepo.delUserRoleByRoleId(roleId);
    }

    @Transactional
    @Override
    public void updateAdminRole(AdminRole adminRole) {
        AdminRole adminRoleByRole = adminRoleRepo.getAdminRoleByRole(adminRole.getRole());
        if (adminRoleByRole == null || adminRoleByRole.getId().equals(adminRole.getId())) {
            adminRoleRepo.updateById(adminFactory.adminRole2AdminRolePO(adminRole));
            //删除角色权限
            adminRolePermissionRepo.delRolePermissionByRoleId(adminRole.getId());
            //添加角色权限
            saveRolePermission(adminRole);
            return;
        }
        throw new BizException("角色名称:" + adminRole.getRole() + "已经存在！");
    }

    @Override
    public AdminRole getAdminRole(Long id) {
        Set<Long> roleIds = new HashSet<>();
        roleIds.add(id);
        Set<Long> permissionIdsByRoleIds = adminRolePermissionRepo.getPermissionIdsByRoleIds(roleIds);
        AdminRole adminRole = adminRoleRepo.getAdminRole(id);
        adminRole.setPermissionIds(permissionIdsByRoleIds);
        return adminRole;
    }

    @Override
    public List<AdminRole> getAdminRolesByUserId(Long userId) {
        return adminRoleRepo.getAdminRolesByIds(getRoleIdsByUserId(userId));
    }

    @Override
    public Set<Long> getRoleIdsByUserId(Long userId) {
        return adminUserRoleRepo.getRoleIdsByUserId(userId);
    }

    @Override
    public PageUtil.PageVo pageAdminRole(AdminRole adminRole) {
        return adminRoleRepo.pageAdminRole(adminFactory.adminRole2AdminRolePO(adminRole));
    }

    private void saveRolePermission(AdminRole adminRole) {
        if (CollectionUtil.isNotEmpty(adminRole.getPermissionIds())) {
            List<AdminRolePermissionPo> adminRolePermissionPoList = new ArrayList<>();
            for (Long permissionId : adminRole.getPermissionIds()) {
                AdminRolePermissionPo adminRolePermissionPO = AdminRolePermissionPo.builder().roleId(adminRole.getId()).permissionId(permissionId).build();
                adminRolePermissionPO.setId(redisService.genAutoIncrID(RedisConstant.CLUSTER1, AdminRolePermissionPo.key));
                adminRolePermissionPoList.add(adminRolePermissionPO);
            }
            adminRolePermissionRepo.saveBatch(adminRolePermissionPoList);
        }
    }
}
